﻿using System;
using System.Text;
using System.Web;
using _5E.Infrastructure.Logging;
using Melee.Controller.Storage;
using Newtonsoft.Json;

namespace Melee.Controller.Handlers
{
    public abstract class AsyncHandlerBase : IHttpAsyncHandler
    {
        public bool IsReusable { get { return true; } }

        public abstract IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData);

        public void EndProcessRequest(IAsyncResult result)
        {
            AsyncResult asyncResult = result as AsyncResult;
            IHttpStorage storage = HttpStorageFactory.GetStorage(asyncResult.Context);

            object ex;
            if (storage.TryRetrieve(HttpStorageKeys.Exception, out ex))
                WriteLog(ex as Exception);

            AjaxResult ajaxResult;
            if (storage.Contains(HttpStorageKeys.NotLogin))
                ajaxResult = new AjaxResult("无法获取数据,请重新登录!");
            else
                ajaxResult = CreateAjaxResultBy(storage);

            string json = string.Empty;
            try
            {
                json = JsonConvert.SerializeObject(ajaxResult);
            }
            catch (Exception ee)
            {
                WriteLog(ee as Exception);
                ajaxResult = new AjaxResult("未知错误,请与管理员联系!");
                json = JsonConvert.SerializeObject(ajaxResult);
            }
            asyncResult.Context.Response.Write(json);
            asyncResult.Context.Response.End();
        }

        private AjaxResult CreateAjaxResultBy(IHttpStorage storage)
        {
            AjaxResult ajaxResult = new AjaxResult();

            object success;
            if (storage.TryRetrieve(HttpStorageKeys.Success, out success))
                ajaxResult.Success = Convert.ToBoolean(success);

            object data;
            if (storage.TryRetrieve(HttpStorageKeys.Data, out data))
                ajaxResult.Data = data;

            object message;
            if (storage.TryRetrieve(HttpStorageKeys.Message, out message))
                ajaxResult.Message = message.ToString();

            return ajaxResult;
        }

        private void WriteLog(Exception ex)
        {
            if (null != ex)
            {
                StringBuilder log = new StringBuilder()
                    .Append("Message:").AppendLine()
                    .AppendFormat("    {0}", ex.Message).AppendLine()
                    .Append("Source:").AppendLine()
                    .AppendFormat("    {0}", ex.Source).AppendLine()
                    .Append("StackTrace:").AppendLine()
                    .Append(ex.StackTrace);
                LoggingFactory.Logger.Log(log.ToString());
            }
        }

        public void ProcessRequest(HttpContext context)
        { }
    }
}
